﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace CPPEI.ETL.TestApp
{
    class TestTaskPool
    {
        private static EventWaitHandle s_handler = new EventWaitHandle(false, EventResetMode.ManualReset);
        public static void Test()
        {

            //for (int index = 0; index < 5; index++)
            //{
            //    TaskPool.ActualRun("1", Guid.NewGuid());
            //}
            for (int index = 0; index < 10; index++)
            {
                Thread thread = new Thread(Running);
                thread.Start();
            }
            s_handler.Set();
            Thread.Sleep(10);

            for (int r = 0; r < 20; r++ )
            {
                for (int index = 0; index < 5; index++)
                {
                    Thread thread = new Thread(Running);
                    thread.Start();
                }
                Thread.Sleep(10);
            }
        }
        private static void Running()
        {
            s_handler.WaitOne();
            Guid taskId = Guid.NewGuid();
            //Console.WriteLine(taskId + ":start");
            TaskPool.Start("", taskId);
        }
    }

    public class MemObj
    {
        private Guid id;
        public MemObj()
        {
            id = Guid.NewGuid();
            Debug.WriteLine("init:" + id.ToString());
        }

        ~MemObj()
        {
            Debug.WriteLine("release:" + id.ToString());
        }

        public int Test(int a, int b)
        {
            return a + b;
        }
    }

    public class TaskPool
    {
        public class TaskInfo
        {
            public string UserId;
            public Guid TaskId;
        }

        private static TaskPool s_pool = new TaskPool();

        private static List<TaskInfo> s_taskInfo = new List<TaskInfo>();
        private static object s_lockObj = new object();
        private static bool s_isRunning = false;

        private static Thread s_thread = null;

        public static void Start(string userId, Guid taskId)
        {
            lock (s_lockObj)
            {
                s_taskInfo.Add(new TaskInfo() { UserId = userId, TaskId = taskId });

                if(s_thread == null)
                {
                    s_thread = new Thread(Running);
                    s_thread.Start();
                }
            }
        }

        private static void Running()
        {
            bool isRunning = true;
            while (isRunning)
            {
                // 取出第一个拿来运行
                TaskInfo task = s_taskInfo[0];
                ActualRun(task.UserId, task.TaskId);
                lock (s_lockObj)
                {
                    s_taskInfo.RemoveAt(0);
                    if(s_taskInfo.Count == 0)
                    {
                        s_thread = null;
                        isRunning = false;
                    }
                }
            }
        }

        private static void ActualRun()
        {
            if (s_taskInfo.Count > 0)
            {
                // 取出第一个拿来运行
                TaskInfo task = s_taskInfo[0];
                lock (s_lockObj)
                {
                    s_taskInfo.RemoveAt(0);
                }
                ActualRun(task.UserId, task.TaskId);

                ActualRun();
            }
        }

        public static void ActualRun(string userId, Guid taskId)
        {
            s_isRunning = true;
            MemObj obj = new MemObj();
            obj.Test(1, 4);
            Thread.Sleep(500);
            Console.WriteLine(taskId.ToString() + ":finished");
            s_isRunning = false;
        }
    }
}
